class BlueprintNode {
    constructor(id, title, position = { x: 0, y: 0 }) {
        this.id = id;
        this.title = title;
        this.position = position;
        this.inputPins = [];
        this.outputPins = [];
        this.width = 200;
        this.height = 120;
        this.isSelected = false;

        // 端点样式配置
        this.pinStyle = {
            // 执行端点样式
            exec: {
                shape: "triangle", // 三角形
                size: 10,
                fillColor: "#FFA500",
                strokeColor: "#CC8400",
                strokeWidth: 1,
                direction: "left" // 输入端点方向向左，输出向右
            },
            // 数据端点样式
            data: {
                shape: "circle",  // 圆形
                size: 8,
                fillColor: "#4A4A4A",
                strokeColor: "#2A2A2A",
                strokeWidth: 1
            },
            // 间距和布局
            layout: {
                horizontalSpacing: 15,  // 端点与节点的水平间距
                verticalSpacing: 20,    // 端点间的垂直间距
                startY: 45,             // 第一个端点的垂直起始位置
                labelOffset: 12         // 标签与端点的间距
            }
        };
    }

    // 更新获取端点位置的方法
    getPinPosition(pinName, isInput) {
        const pins = isInput ? this.inputPins : this.outputPins;
        const visiblePins = pins.filter(p => !p.hidden);
        const pinIndex = visiblePins.findIndex(p => p.name === pinName);

        if (pinIndex === -1) return null;

        const pinType = visiblePins[pinIndex].isExec ? "exec" : "data";
        const pinConfig = this.pinStyle[pinType];
        const layout = this.pinStyle.layout;

        const x = isInput
            ? this.position.x - layout.horizontalSpacing
            : this.position.x + this.size.width + layout.horizontalSpacing;

        const y = this.position.y + layout.startY + (pinIndex * layout.verticalSpacing);

        return {
            x,
            y,
            type: pinType,
            config: pinConfig,
            isInput
        };
    }

    addInputPin(name, type) {
        this.inputPins.push({ name, type });
        this.updateSize();
    }

    addOutputPin(name, type) {
        this.outputPins.push({ name, type });
        this.updateSize();
    }

    updateSize() {
        const pinCount = Math.max(this.inputPins.length, this.outputPins.length);
        this.height = 30 + Math.max(3, pinCount) * 20 + 10;
    }

    serialize() {
        return {
            id: this.id,
            type: this.constructor.name,
            title: this.title,
            position: this.position,
            inputPins: this.inputPins,
            outputPins: this.outputPins
        };
    }

    static deserialize(data) {
        const node = new this(data.id, data.title, data.position);
        node.inputPins = data.inputPins;
        node.outputPins = data.outputPins;
        return node;
    }
}


// VariableNodes.js
class VariableNode extends BlueprintNode {
    constructor(id, title, varId, blueprintSystem, position = { x: 0, y: 0 }) {
        super(id, title, position);
        this.varId = varId;
        this.blueprintSystem = blueprintSystem;
        this.width = 180;
    }
}

class GetVariableNode extends VariableNode {
    constructor(id, varId, blueprintSystem, position = { x: 0, y: 0 }) {
        const varData = blueprintSystem.getVariable(varId);
        super(id, `Get ${varData.name}`, varId, blueprintSystem, position);
        this.addOutputPin("Value", varData.type);
    }
}

class SetVariableNode extends VariableNode {
    constructor(id, varId, blueprintSystem, position = { x: 0, y: 0 }) {
        const varData = blueprintSystem.getVariable(varId);
        super(id, `Set ${varData.name}`, varId, blueprintSystem, position);
        this.addInputPin("Exec", "exec");
        this.addInputPin("Value", varData.type);
        this.addOutputPin("Exec", "exec");
    }
}

class VariableGetterNode extends VariableNode {
    constructor(id, varId, blueprintSystem, position = { x: 0, y: 0 }) {
        const varData = blueprintSystem.getVariable(varId);
        super(id, varData.name, varId, blueprintSystem, position);
        this.addOutputPin("Value", varData.type);
    }
}


class PrintStringNode extends BlueprintNode {
    constructor(id, position = { x: 0, y: 0 }) {
        super(id, "Print String", position);
        this.addInputPin("Exec", "exec");
        this.addInputPin("Message", "string");
    }
}

class BranchNode extends BlueprintNode {
    constructor(id, position = { x: 0, y: 0 }) {
        super(id, "Branch", position);
        this.addInputPin("Exec", "exec");
        this.addInputPin("Condition", "boolean");
        this.addOutputPin("True", "exec");
        this.addOutputPin("False", "exec");
    }
}

class DelayNode extends BlueprintNode {
    constructor(id, position = { x: 0, y: 0 }) {
        super(id, "Delay", position);
        this.addInputPin("Exec", "exec");
        this.addInputPin("Duration", "float");
        this.addOutputPin("Exec", "exec");
    }
}

class MathNode extends BlueprintNode {
    constructor(id, position = { x: 0, y: 0 }) {
        super(id, "Math", position);
        this.addInputPin("A", "float");
        this.addInputPin("B", "float");
        this.addOutputPin("Result", "float");
    }
}

class ComparisonNode extends BlueprintNode {
    constructor(id, position = { x: 0, y: 0 }) {
        super(id, "Comparison", position);
        this.addInputPin("A", "float");
        this.addInputPin("B", "float");
        this.addOutputPin("Result", "boolean");
    }
}
